/**
 * @file
 */

#include "nosal/exec/exec_error_domain.h"
#include "nosal/core/error_domain.h"

namespace netaos {
namespace nosal {
namespace exec {

ExecException::ExecException(core::ErrorCode errorCode) noexcept
    : netaos::nosal::core::Exception(std::move(errorCode))
{ }

ExecErrorDomain::ExecErrorDomain() noexcept
    : netaos::nosal::core::ErrorDomain(kId)
{ }

const char* ExecErrorDomain::Name() const noexcept
{
    return "Exec";
}

const char* ExecErrorDomain::Message(core::ErrorDomain::CodeType errorCode) const noexcept
{
    ExecErrc const code = static_cast<ExecErrc>(errorCode);
    switch (code) {
    case ExecErrc::kGeneralError:
        return "Some unspecified error occurred";
    case ExecErrc::kCommunicationError:
        return "Communication error occurred";
    case ExecErrc::kMetaModelError:
        return "Wrong meta model identifier passed to a function";
    case ExecErrc::kCancelled:
        return "Transition to the requested Function Group state was cancelled by a newer request";
    case ExecErrc::kFailed:
        return "Transition to the requested Function Group state failed";
    case ExecErrc::kFailedUnexpectedTerminationOnEnter:
        return "Transition failed as Unexpected Termination during Process start occured";
    case ExecErrc::kInvalidTransition:
        return "Transition rejected as request is invalid.";
    case ExecErrc::kAlreadyInState:
        return "Transition failed as Function Group is already in requested state";
    case ExecErrc::kInTransitionToSameState:
        return "Transition failed as Function Group is already switchting to the requested state";
    case ExecErrc::kNoTimeStamp:
        return "No timestamp available for Deterministic Client";
    case ExecErrc::kCycleOverrun:
        return "Deterministic activation cycle time exceeded";
    case ExecErrc::kIntegrityOrAuthenticityCheckFailed:
        return "Transition failed as a process could not be authenticated successfully.";
    default:
        return "Unknown error";
    }

    return "Unknown error";
}

void ExecErrorDomain::ThrowAsException(const core::ErrorCode& errorCode) const noexcept(false)
{
    netaos::nosal::core::ifc::ThrowOrTerminate<ExecException>(errorCode);
}

namespace
{
static const ExecErrorDomain gExecDomain;
}

const core::ErrorDomain& GetExecErrorDomain() noexcept
{
    return gExecDomain;
}

netaos::nosal::core::ErrorCode MakeErrorCode(netaos::nosal::exec::ExecErrc code, netaos::nosal::core::ErrorDomain::SupportDataType data) noexcept
{
    return netaos::nosal::core::ErrorCode(static_cast<netaos::nosal::core::ErrorDomain::CodeType>(code), GetExecErrorDomain(), data);
}

}  // namespace exec
}  // namespace nosal
}  // namespace netaos
